/********************************************************************************
 * Copyright (c)2016-2020, ShenZhen WanJiaAn Technology CO.,LTD.
 * All Rights Reserved.
 *
 * File Name     : DevSd.c
 * Author        : joki.zhu
 * Date          : 2019-10-16
 *
 * Record        :
 * 1.Date        : 2019-10-16
 *   Author      : joki.zhu
 *   Modification: Created file
 ********************************************************************************/

#include "app_common.h"
#include "DevSd.h"
#include "profiles_management.h"
#include "DevConfig.h"
#include "DevWifi.h"
#include "Video.h"

#define SD_PRODCUT_CONFIG_FILE  "/sdcard/b1.txt"

static int sd_config_video_format(void)
{
#if 0
    static char bConfigSuccess = 0;
    
    if (bConfigSuccess) {
        return 0;
    }
#endif

    int ret = 0;
    int width = 0;
    int height = 0;
    int bitrate = 0;
    char value[32] = {0};
    
    ret = read_profile(SD_PRODCUT_CONFIG_FILE, "VIDEO", "width", value);
    if (ret < 0) {
        return -1;
    }
    width = atoi(value);
    
    memset(value, 0, sizeof(value));
    ret = read_profile(SD_PRODCUT_CONFIG_FILE, "VIDEO", "height", value);
    if (ret < 0) {
        return -1;
    }
    height = atoi(value);

    memset(value, 0, sizeof(value));
    ret = read_profile(SD_PRODCUT_CONFIG_FILE, "VIDEO", "bitrate", value);
    if (ret < 0) {
        return -1;
    }
    
    bitrate = atoi(value);
    if (bitrate < 0 || bitrate > 2048) {
        bitrate = 1024;
    }

    LOGI("widht: %d height: %d bitrate: %d\n", width, height, bitrate);

    switch (width)
    {
        case 640:
            height = 360;
            break;
        case 1280:
            height = 720;
            break;
        case 1920:
            height = 1080;
            break;
        default:
            width = 1280;
            height = 720;
            break;
    }
    
    VIDEO_STREAM_ATTR_S stStreamAttr;
    memset(&stStreamAttr, 0, sizeof(stStreamAttr));

    ret = VideoGetOpsHandle()->get_resolution(0, &stStreamAttr);
    if (ret < 0) {
        LOGE("get_resolution failed\n");
        return -1;
    }

    if (stStreamAttr.width == width && stStreamAttr.bitrate == bitrate) {
        return -1;
    }
    
    stStreamAttr.width = width;
    stStreamAttr.height = height;
    stStreamAttr.bitrate = bitrate;
    stStreamAttr.framerate = 15;
    stStreamAttr.nGop = 30;
    stStreamAttr.enVencType = MEDIA_ENC_TYPE_H264;
    stStreamAttr.enRcMode = MEDIA_VENC_RC_MODE_VBR;

    
	ret = VideoGetOpsHandle()->set_resolution_without_config(0, stStreamAttr);
#if 0
    if (ret >= 0) {
        bConfigSuccess = 1;
    }
#endif
    
    return 0;
}

static int sd_config_wifi(void)
{
    static char bConfigSuccess = 0;

    if (bConfigSuccess) {
        return 0;
    }
    
    if (0 != access(SD_PRODCUT_CONFIG_FILE, F_OK)) {
        return -1;
    }

    int ret = 0;
    char ssid[64] = "";
    char password[64] = "";
    
    ret = read_profile(SD_PRODCUT_CONFIG_FILE, "WIFI", "ssid", ssid);
    if (ret < 0) {
        return -1;
    }

    ret = read_profile(SD_PRODCUT_CONFIG_FILE, "WIFI", "password", password);
    if (ret < 0) {
        return -1;
    }
    
    LOGI("ssid: %s password: %s\n", ssid, password);

    char confSsid[64] = "";
    char confPassword[64] = "";
    DevConfigGetWifi(confSsid, confPassword, NULL);
    
    if (0 != strcmp(confSsid, ssid) || 0 != strcmp(confPassword, password)) 
    {
        WIFI_ENCRYPT_TYPE_E enEncryptType;
        
        if (0 == strlen(password)) {
            enEncryptType = WIFI_ENCRYPT_OPEN;
        } else {
            enEncryptType = WIFI_ENCRYPT_WPA_WPA2;
        }

        if (1 == WifiCheckSsidIsExistent(ssid)) 
        {
            ret = WifiSetConnect(ssid, password, enEncryptType);
            if (ret >= 0) {
                bConfigSuccess = 1;
            }
        }
    }
    else
    {
        bConfigSuccess = 1;
    }
    
    return 0;
}

void *tskSdProc(void*args)
{
    SET_THREAD_NAME("tskSdProc");
    pthread_detach(pthread_self());  

    int cnt = 0;
    
#ifdef LOSCFG_DRIVERS_MMC
    LOGD("MMC dev init ...\n");
    extern int SD_MMC_Host_init(void);
    SD_MMC_Host_init();
#endif
    
    while (1)
    {
        if (SdCheckIsExistent()) 
        {
            if (!SdCheckIsMount(SDCARD_DEVICE, SDCARD_MOUNT_PATH))
            {
                 SdMount();
            }
            else
            {
                sd_config_wifi();
//                if (cnt > 5) { /* 5 seconds */
                if (cnt != 0 && cnt%3 == 0) { /* 5 seconds */
                    sd_config_video_format();
                }
            }
        }
        cnt++;
        sleep(1);
    }

    pthread_exit(0);
}

int SdInit()
{
    int ret = 0;
    pthread_t pid;
    
    ret = pthread_create(&pid, NULL, &tskSdProc, NULL);
    if (ret != 0) {
        LOGE("pthread_create tskSdProc failed!\n");
        return -1;
    }

    return 0;
}

int SdMount(void)
{
    int ret = 0;
    int retry_count = 0;
    char bMountOk = 0;
    
    /* wait dev node ready */
    do {
        usleep(100000);
        ret = access(SDCARD_DEVICE, 0);
    } while ((ret < 0) && (retry_count++ < 20));

    if (ret < 0) {
        LOGD("%s is not exit!\n", SDCARD_DEVICE);
        return ret;
    }

retry:
    ret = mount(SDCARD_DEVICE, SDCARD_MOUNT_PATH, "vfat", 0, 0);
    if (ret) {
        LOGE("mount %s to sdcard err:%d\n", SDCARD_DEVICE, ret);
        if (retry_count++ < 2) {
            LOGE("!!! warning! format %s!\n", SDCARD_DEVICE);
            format(SDCARD_DEVICE, 128, 2);
            goto retry;
        } else {
        }
    } else {
        LOGI("sdcard %s mount to %s success\n", SDCARD_DEVICE, SDCARD_MOUNT_PATH);
        bMountOk = 1;
    }    

    return bMountOk;
}

int SdCheckIsExistent(void)
{
    char bExistent = 0;
    
    if (0 == access(SDCARD_DEVICE, F_OK)) {
        bExistent = 1;
    } else {
        bExistent = 0;
    }
    
    return bExistent;
}


int SdCheckIsMount(char *deviceName, char *mountPath)
{
    FILE *fp = NULL;
    char strDevName[24] = {0};
    char strDirName[24] = {0};
    char strFileType[16] = {0};
    char strMountParam[255] = {0};
    int other[2] = {0};
    char buf[255] = {0};
    char bMount = 0;

    if (deviceName == NULL || mountPath == NULL) {
        LOGE("Param is invalid!\n");
        return bMount ;
    }

    if (!SdCheckIsExistent()) {
        return bMount;
    }
    
    fp = fopen("/proc/mounts", "r");
    if (fp == NULL) {
        LOGE("fopen /proc/mounts failed\n");
        return bMount;
    }

    while (!feof(fp))
    {
        memset(buf, 0, sizeof(buf));
        fgets((char *)buf, sizeof(buf) - 1, fp);
        sscanf(buf, "%s %s %s %s %s %d %d", 
            strDevName, strDirName, strFileType, strMountParam, &other[0], &other[1]);
#ifdef __HuaweiLite__
        if (0 == strcmp(mountPath, strDirName))
#else
         if (0 == strcmp(deviceName, strDevName) && 0 == strcmp(mountPath, strDirName))
#endif /* __HuaweiLite__ */
        {
            bMount = 1;
        }
    }

    fclose(fp);

    return bMount;
}

int SdUmount()
{
    return 0;
}

int SdFormat()
{
    format(SDCARD_DEVICE, 128, 2);

    return 0;
}

int SdDeinit()
{
    return 0;
}

